package demo.java8.SumTest;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 10w个正整数相加，如何计算才快速
 * Created by Administrator on 2017/5/8.
 */
public class IntSumTest {
    int[] valueNum = new int[10000000];//10w个数

    public IntSumTest(int maxNum){
        Random r = new Random();
        for(int i=0;i<valueNum.length;i++){
            valueNum[i] = r.nextInt(maxNum);
        }
    }

    /**
     * 直接计算
     * @return
     */
    public long count(){
        long sum = 0;
        for(int i=0;i<valueNum.length;i++){
            sum+= valueNum[i];
        }
        return sum;
    }
    /**
     * 使用计数方法计算
     * 理论上的好处在于java栈内的管理方式是所有成员变量都会记录
     * @return
     */
    public long countSum(){
        long sum = 0;
        for(int i=0;i<valueNum.length;i++){
            sum = sum( sum,valueNum[i]);
        }
        return sum;
    }
    public long sum(long sum ,int num){
        return sum+num;
    }
    /**
     * 使用数组计数，然后在各个数字相乘，得到结果
     * 该方法的好处在于可以释放大量对象
     * 缺点在于，如果数字的分布范围太大，效果就不明显
     */
    public long mapCount(){
        long sum = 0;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i=0;i<valueNum.length;i++){
            map.put(valueNum[i],map.get(valueNum[i])==null?0:map.get(valueNum[i])+1);
        }
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            sum+= entry.getKey()*entry.getValue();
        }
        return sum;
    }
    /**
     * 多线程计算，分10组计算，分别汇总结果
     */
    public long threadCount(){
        long sum = 0;
        long[] sumNum = new long[10];
        for (int i = 0; i < 10; i++) {
            MyThread my = new MyThread(sumNum,valueNum,i);
            my.run();
        }
        for (int i = 0; i < 10; i++) {
            sum += sumNum[i];
        }
        return sum;
    }
    /**
     * 分10组计算，分别汇总结果
     */
    public long reduceCount(){
        long sum = 0;
        long[] sumNum = new long[10];
        for (int i = 0; i < 10; i++) {
            int temp = i*10000;
            long max = temp+10000;
            for (int j = temp; j < max; j++) {
                sumNum[i]+= valueNum[j];
            }
        }
        for (int i = 0; i < 10; i++) {
            sum += sumNum[i];
        }
        return sum;
    }
}
